﻿using SQ.Domain;
using SQ.Infrastructure.Mappings;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Infrastructure.DependencyResolution;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SQ.Infrastructure.DataContexts
{
    [DbConfigurationType(typeof(EntityFrameworkDbConfiguration))]
    public class SmartQueueDataContext : DbContext
    {
        public SmartQueueDataContext()
            : base("SmartQueue")
        {
            Configuration.LazyLoadingEnabled = true;
            Configuration.ProxyCreationEnabled = true;
            //Database.SetInitializer<SmartQueueDataContext>(new SmartQueueDataContextInitialize());
            Database.SetInitializer<SmartQueueDataContext>(null);
        }

        public DbSet<Estabelecimento> Estabelecimentos
        {
            get;
            set;
        }

        public DbSet<Endereco> Enderecos
        {
            get;
            set;
        }

        public DbSet<Usuario> Usuarios
        {
            get;
            set;
        }

        public DbSet<Fila> Filas
        {
            get;
            set;
        }

        public DbSet<IntegranteFila> IntegrantesFila
        {
            get;
            set;
        }


        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new EnderecoMap());
            modelBuilder.Configurations.Add(new UsuarioMap());
            modelBuilder.Configurations.Add(new EstabelecimentoMap());
            modelBuilder.Configurations.Add(new FilaMap());
            modelBuilder.Configurations.Add(new IntegrantesFilaMap());
            base.OnModelCreating(modelBuilder);
        }
    }

    public class SmartQueueDataContextInitialize : DropCreateDatabaseAlways<SmartQueueDataContext>
    {
        protected override void Seed(SmartQueueDataContext context)
        {
            AdicionarUsuarios(context);
            AdicionarEstabelecimentos(context);

            CriarFilas(context);

            base.Seed(context);
        }

        private void CriarFilas(SmartQueueDataContext context)
        {
            foreach (var estabelecimento in context.Estabelecimentos)
            {
                Fila fi = new Fila()
                {
                    DataFimFila = DateTime.MinValue,
                    DataInicioFila = DateTime.Now.Date.AddHours(DateTime.Now.Hour).AddMinutes(DateTime.Now.Minute).AddSeconds(DateTime.Now.Second),
                    Estabelecimento = estabelecimento,
                    EstabelecimentoId = estabelecimento.Id,
                    Id = estabelecimento.Id,
                    TempoEsperaMedio = 5
                };

                context.Filas.Add(fi);
            }

            context.SaveChanges();
        }

        private void AdicionarEstabelecimentos(SmartQueueDataContext context)
        {
                context.Estabelecimentos.Add(new Estabelecimento()
                {
                    Id = 1,
                    ContatoTelefonico = "44912311",
                    Email = "churrascaria1305@gmail.com",
                    Endereco = new Endereco()
                    {
                        Id = 1,
                        CEP = "09110220",
                        Cidade = "Santo André",
                        Estado = "SP",
                        EnderecoComercial = "Rua 25 de março",
                        Complemento = "nº 152"
                    },
                    EnderecoId = 1,
                    Nome = "Churrascaria 13 de Maio",
                    Password = "HFD"
                });

                context.Estabelecimentos.Add(new Estabelecimento()
                {
                    Id = 1,
                    ContatoTelefonico = "44112322",
                    Email = "supersushi@gmail.com",
                    Endereco = new Endereco()
                    {
                        Id = 2,
                        CEP = "09100220",
                        Cidade = "São Bernardo",
                        Estado = "SP",
                        EnderecoComercial = "Rua do Centro",
                        Complemento = "nº 51"
                    },
                    EnderecoId = 1,
                    Nome = "Super Sushi",
                    Password = "HFD"
                });

                context.Estabelecimentos.Add(new Estabelecimento()
                {
                    Id = 1,
                    ContatoTelefonico = "44112322",
                    Email = "italianhouse@gmail.com",
                    Endereco = new Endereco()
                    {
                        Id = 2,
                        CEP = "09080220",
                        Cidade = "São Caetano",
                        Estado = "SP",
                        EnderecoComercial = "Avenida Goiás",
                        Complemento = "nº 510"
                    },
                    EnderecoId = 1,
                    Nome = "Italian House",
                    Password = "HFD"
                });

                context.Estabelecimentos.Add(new Estabelecimento()
                {
                    Id = 1,
                    ContatoTelefonico = "44112322",
                    Email = "mexicangrill@gmail.com",
                    Endereco = new Endereco()
                    {
                        Id = 2,
                        CEP = "09111220",
                        Cidade = "São Bernardo",
                        Estado = "SP",
                        EnderecoComercial = "Avenida Kennedy",
                        Complemento = "nº 1100"
                    },
                    EnderecoId = 1,
                    Nome = "Mexican Grill",
                    Password = "HFD"
                });

            context.SaveChanges();
        }

        private void AdicionarUsuarios(SmartQueueDataContext context)
        {
            context.Usuarios.Add(new Usuario()
            {
                Id = 1,
                Documento = "381.936.248-74",
                Email = "luiz@gmail.com",
                Nome = "Luiz Guilherme Lima de Mattos",
                Password = "HFD",
                DataNascimento = new DateTime(1990, 11, 29).Date,
                ContatoTelefonico = "11972857748",
            });

            context.Usuarios.Add(new Usuario()
            {
                Id = 2,
                Documento = "381.123.124-12",
                Email = "iago@gmail.com",
                Nome = "Iago Biagioni",
                Password = "HFD",
                DataNascimento = new DateTime(1990, 11, 10).Date,
                ContatoTelefonico = "11983868027"
            });

            context.Usuarios.Add(new Usuario()
            {
                Id = 3,
                Documento = "381.123.124-12",
                Email = "Rodrigo@gmail.com",
                Nome = "Rodrigo Anderson Daniel",
                Password = "HFD",
                DataNascimento = new DateTime(1990, 11, 1).Date,
                ContatoTelefonico = ""
            });

            context.SaveChanges();
        }
    }

    internal sealed class EntityFrameworkDbConfiguration : DbConfiguration
    {
        private const string SqlServerManifestToken = @"2012";

        public EntityFrameworkDbConfiguration()
        {
            this.AddDependencyResolver(new SingletonDependencyResolver<IManifestTokenResolver>(new ManifestTokenService()));
        }

        private sealed class ManifestTokenService : IManifestTokenResolver
        {
            private static readonly IManifestTokenResolver DefaultManifestTokenResolver = new DefaultManifestTokenResolver();

            public string ResolveManifestToken(DbConnection connection)
            {
                if (connection is SqlConnection)
                {
                    return SqlServerManifestToken;
                }

                return DefaultManifestTokenResolver.ResolveManifestToken(connection);
            }
        }
    }
}
